/*
 * main.c
 *
 *  Created on: Nov 21, 2011
 *      Author: matthias
 */
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <netdb.h>

#define PORT "6667"
#define MAXDATASIZE 1000

char username[50];
char realname[50];
char nickname[50];
int newnickname = 1;
int stop = 1;
int clossed = 1;
int admin = 0;

void reconnect(int *sockfd) {
	struct addrinfo hints, *servinfo;
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	getaddrinfo("localhost", PORT, &hints, &servinfo);

	*sockfd = socket(servinfo->ai_family, servinfo->ai_socktype,
			servinfo->ai_protocol);

	connect(*sockfd, servinfo->ai_addr, servinfo->ai_addrlen);
	freeaddrinfo(servinfo);
}
void login(int sockfd) {

	char datatosend[MAXDATASIZE];
	strcpy(datatosend, "Nick ");
	strcat(datatosend, nickname);
	strcat(datatosend, "\n USER ");
	strcat(datatosend, username);
	strcat(datatosend, " myhost WeIRCd :");
	strcat(datatosend, realname);
	strcat(datatosend, "\n");
	send(sockfd, datatosend, strlen(datatosend), 0);
}
void loop(int *sockfd) {
	char data[MAXDATASIZE];
	char *data2;
	char buf[MAXDATASIZE];
	int numbytes;
	char *result;
	int true = 0;
	int firstpong = 0;
	while (stop) {

		numbytes = recv(*sockfd, buf, MAXDATASIZE - 1, 0);

		buf[numbytes] = '\0';

		result = strtok(buf, "\n");
		//printf("%s\n",result);
		while (result != NULL) {
			if (strstr(result, "PRIVMSG")) {

				result = result + 1;

				data2 = strtok_r(result, "!", &result);

				strcpy(data, data2);
				strcat(data, "( ");
				data2 = strtok_r(strstr(result, "PRIVMSG ") + 8, " :", &result);
				if (strcmp(data2, nickname) == 0) {
					strcat(data, "privat message");
				} else {
					strcat(data, data2);
				}
				strcat(data, " )==>");

				data2 = strtok_r(result, "\n", &result);
				strcat(data, data2);
				strcat(data, "\0");
				printf("%s\n", data);

			} else if (strstr(result, "321 ")) {
				printf("volgende channels bestaan al\n");
				true = 1;
			} else if (strstr(result, "322 ")) {
				result[strlen(result) - 2] = '\0';
				printf("%s user(s)\n", strstr(result, "#"));
				true = 0;
			} else if (strstr(result, "323 ") && true == 1) {
				printf("er zijn nog geen channels beschikbaar\n");
			} else if (strstr(result, "PING :")) {

				strcat(result, "\n");
				result[1] = 'O';
				send(*sockfd, result, strlen(result), 0);
				if (firstpong == 0) {
					printf("You are logged in correctly!\n");
					printf("you can use the commands listed below:\n");
					printf(
							"\t/who [channel]: gives a list who is in the channel\n");
					printf(
							"\t@nickname [text]: send a private message to nickname\n");
					printf("\t/quit [channel]: going away from a channel\n");
					printf(
							"\t/kick [channel] nickname: if you're an admin, this command kicks someone from the channel.\n");
					printf("\t/list: gives a list of possible channels\n");
					printf(
							"\t#channel: now you can chat in the choosen channel\n");
					printf(
							"\t@privateperson: now you can chat in private with privateperson\n");
					printf(
												"\t/dcc username filename: sends a file (filename) to a user (username)\n");
					printf(
							"\tor you can just chat by typing your message if you're in a channel or private messaging, or try [#channel]/[@private] your message\n\n");
					firstpong = 1;
				}
			} else if (strstr(result,
					"ERROR :Throttled: Reconnecting too fast. Please wait 20 seconds.")) {
				printf("reconnecting to fast , wait 20 seconds \n");
				usleep(20000000);
				reconnect(sockfd);
				//login(*sockfd);
			} else if (strstr(result, "NOTICE AUTH :*** Resolving host name...")) {

				login(*sockfd);
			} else if (strstr(result, "433 ")) {
				newnickname = 0;
				printf("Nickname already exist choose a new nickname.\n");

			} else if (strstr(result, "432 ")) {
				newnickname = 0;
				printf("Nickname is illegal choose a new nickname.\n");

			} else if (strstr(result,
					"ERROR :Closing link: Registration timeout")) {
				printf("program has stopped, do you want to restart? (y/n)\n");
				stop = 0;
				newnickname = 1;

			} else if (strstr(result, " 352 ")) {
				strcpy(data, strstr(result, " irc.mynet.net "));

				strcpy(data, data + 15);
				strcpy(data, strtok_r(data, " ", &data2));

				if (strcmp(data, nickname) == 0) {
					if (strstr(result, "H@")) {
						admin = 1;
						printf("you are the admin\n");
					}
				} else {

					if (strstr(result, "H@")) {
						admin = 0;
						printf("%s is the admin\n", data);
					} else {
						printf("%s is in this channel \n", data);
					}
				}

			} else if (strstr(result, "KICK ")) {

				strcpy(data, strtok_r(strstr(result, ":") + 1, "!", &result));
				strcat(data, " has kicked ");
				data2 = strtok_r(strstr(result, "#") + 1, " ", &result);

				strcat(data, strtok_r(result, " ", &result));

				strcat(data, " from ");

				strcat(data, data2);

				printf("%s\n", data);
			} else if (strstr(result, " 482 ")) {
				strtok_r(strstr(result, " 482 "), ":", &data2);
				printf("%s\n", data2);
			}
			else if(strstr(result," MODE "))
			{
				if(strstr(result," +b "))
				{
					strtok_r(strstr(result," +b "),"*!~",&data2);
				strcpy(data,strtok_r(data2,"\n@",&data2));
				strcat(data, " has been banned from ");
				strcat(data,strtok_r(strstr(result,"#")," ",&data2));
				printf("%s\n",data);
				}

			}
			result = strtok(NULL, "\n");

		}
	}
	shutdown(*sockfd, 2);
}

int main(void) {

	char datatosend[MAXDATASIZE];
	char data[MAXDATASIZE];
	char *data2;
	char channel[50] = "";
	int sockfd;
	pthread_t thread;

	printf("please enter a nickname\n");
	gets(nickname);
	printf("please enter a username\n");
	gets(username);
	printf("please enter your real name\n");
	gets(realname);
	reconnect(&sockfd);
	pthread_create(&thread, NULL, (void *) &loop, (int *) &sockfd);

	while (strcmp(datatosend, "stop") && clossed) {

		//scanf("%s", datatosend);
		gets(data);

		if (data[0] == '#') {
			strcpy(datatosend, "JOIN ");
			strcpy(channel, strtok_r(data, " \n", &data2));
			strcat(datatosend, channel + 1);

			strcat(datatosend, "\n");
			send(sockfd, datatosend, strlen(datatosend), 0);

			if (strlen(data2) > 0) {
				strcpy(datatosend, "PRIVMSG ");
				strcat(datatosend, channel);
				strcat(datatosend, " :");
				data2[strlen(data2)] = '\0';
				strcat(datatosend, data2);
				strcat(datatosend, "\n");
				send(sockfd, datatosend, strlen(datatosend), 0);
			}
		} else if (strstr(data, "/who")) {
			data2 = "";
			strtok_r(data, " ", &data2);

			if (strlen(data2) == 0) {
				if (strcmp(channel, "") == 0) {
					printf("first choose a channel\n");
				} else if (!strstr(channel, "#")) {
					printf("you can't quit personal channels!\n");
				} else {
					strcpy(datatosend, "WHO ");
					strcat(datatosend, channel);
					strcat(datatosend, "\n");
					strcpy(channel, "");
					send(sockfd, datatosend, strlen(datatosend), 0);

				}
			} else {
				strcpy(datatosend, "JOIN ");
				strcpy(channel, data2);
				strcat(datatosend, channel + 1);

				strcat(datatosend, "\n");
				send(sockfd, datatosend, strlen(datatosend), 0);
				strcpy(datatosend, "WHO  ");
				strcat(datatosend, data2);
				strcat(datatosend, "\n");
				send(sockfd, datatosend, strlen(datatosend), 0);
			}

		} else if (data[0] == '@') {

			strcpy(datatosend, "PRIVMSG ");
			strcpy(channel, strtok_r(data + 1, " \n", &data2));
			strcat(datatosend, channel);
			strcat(datatosend, " :");
			if (strlen(data2) > 0) {
				data2[strlen(data2)] = '\0';
				strcat(datatosend, data2);
				strcat(datatosend, "\n");
				send(sockfd, datatosend, strlen(datatosend), 0);
			}
		} else if (strstr(data, "/quit")) {
			data2 = "";
			strtok_r(data, " ", &data2);
			printf("%s\n", data2);
			if (strlen(data2) == 0) {
				if (strcmp(channel, "") == 0) {
					printf("first choose a channel\n");
				} else if (!strstr(channel, "#")) {
					printf("you can't quit personal channels!\n");
				} else {
					strcpy(datatosend, "PART ");
					strcat(datatosend, channel);
					strcat(datatosend, "\n");
					strcpy(channel, "");
					send(sockfd, datatosend, strlen(datatosend), 0);

				}
			} else {
				strcpy(datatosend, "PART ");
				strcat(datatosend, data2);
				strcat(datatosend, "\n");
				send(sockfd, datatosend, strlen(datatosend), 0);
			}

		} else if (strstr(data, "/kick")) {
			data2 = "";


			if (!strstr(data, "#")) {
				if (strcmp(channel, "") == 0) {
					printf("first choose a channel\n");
				} else {
					strtok_r(data, " ", &data2);
					if (strlen(data2) > 1) {
						strcpy(datatosend, "KICK ");
						strcat(datatosend, channel);

						strcat(datatosend, " ");
						strcat(datatosend, data2);
						strcat(datatosend, "\n");

						send(sockfd, datatosend, strlen(datatosend), 0);
					} else {
						printf("please enter a name!\n");
					}
				}
			} else {
				strtok_r(data, " ", &data2);

				if (strlen(data2) > 1) {
					strcpy(datatosend, "KICK ");
					strcat(datatosend, channel);
					strtok(data, " ");
					strcat(datatosend, " ");
					strcat(datatosend, data2);
					strcat(datatosend, "\n");

					send(sockfd, datatosend, strlen(datatosend), 0);
				} else {
					printf("please enter a name!\n");
				}
			}

		}

		else if (strcmp(data, "/list") == 0) {
			strcpy(datatosend, "LIST\n");

			send(sockfd, datatosend, strlen(datatosend), 0);
		} else if (newnickname == 0) {
			strcpy(nickname, data);
			strcpy(datatosend, "Nick ");
			strcat(datatosend, nickname);
			strcat(datatosend, "\n");
			newnickname = 1;
			send(sockfd, datatosend, strlen(datatosend), 0);
		} else if (stop == 0) {
			if (strcmp(data, "y") == 0) {
				printf("trying to reconnect\n");
				reconnect(&sockfd);
				pthread_create(&thread, NULL, (void *) &loop, (int *) &sockfd);
				stop = 1;
			} else {
				printf("clossing!\n");
				clossed = 0;
			}
		} else if (strstr(data, "/ban")) {
			data2 = "";

			if (!strstr(data, "#")) {
				if (strcmp(channel, "") == 0) {
					printf("first choose a channel\n");
				} else {
					strtok_r(data, " ", &data2);
					if (strlen(data2) > 1) {
						strcpy(datatosend, "MODE ");
						strcat(datatosend, channel);
						strcat(datatosend, " +b ");
						strcat(datatosend, " ");
						strcat(datatosend, data2);
						strcat(datatosend, "\n");

						send(sockfd, datatosend, strlen(datatosend), 0);
					} else {
						printf("please enter a name!\n");
					}
				}
			} else {
				strtok_r(data, " ", &data2);

				if (strlen(data2) > 1) {
					strcpy(datatosend, "MODE ");
					strcat(datatosend, channel);
					strcat(datatosend, " +b ");
					strtok(data, " ");
					strcat(datatosend, " ");
					strcat(datatosend, data2);
					strcat(datatosend, "\n");

					send(sockfd, datatosend, strlen(datatosend), 0);
				} else {
					printf("please enter a name!\n");
				}
			}

		}

		else {
			if (strcmp(channel, "") == 0) {
				printf("first choose a channel\n");
			} else {
				strcpy(datatosend, "PRIVMSG ");
				strcat(datatosend, channel);
				strcat(datatosend, " :");
				data[strlen(data)] = '\0';
				strcat(datatosend, data);
				strcat(datatosend, "\n");
				send(sockfd, datatosend, strlen(datatosend), 0);
			}
		}
	}

	return 0;
}

